package blockchain

import (
	"context"
	"math/big"
	"strings"

	"private-domain-overseas-service/admin/business/api/internal/svc"
	"private-domain-overseas-service/admin/business/api/internal/types"
	"private-domain-overseas-service/pkg/constant"

	"github.com/ethereum/go-ethereum"
	"github.com/ethereum/go-ethereum/accounts/abi"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/zeromicro/go-zero/core/logx"
)

type BlockchainWalletBalanceLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// 钱包余额接口
func NewBlockchainWalletBalanceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BlockchainWalletBalanceLogic {
	return &BlockchainWalletBalanceLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *BlockchainWalletBalanceLogic) BlockchainWalletBalance() (resp *types.BlockchainWalletBalanceResponse, err error) {
	// 连接到zkSync节点

	client, err := ethclient.Dial(l.svcCtx.Config.Blockchain.ZkSyncExplorerURL)
	if err != nil {
		logx.Errorf("Failed to connect: %v", err)
	}
	defer client.Close()

	// 定义钱包地址和代币合约地址
	mywallet := common.HexToAddress(l.svcCtx.Config.Blockchain.BackendAddress)
	hzbContract := common.HexToAddress(l.svcCtx.Config.Blockchain.HzbContract)
	// ERC-20 balanceOf ABI

	erc20ABI := constant.Erc20ABI
	// 解析ABI
	parsedABI, err := abi.JSON(strings.NewReader(erc20ABI))
	if err != nil {
		logx.Errorf("解析ABI失败: %v", err)
	}

	data, err := parsedABI.Pack("balanceOf", mywallet)
	if err != nil {
		logx.Errorf("打包数据失败: %v", err)
	}

	// 调用合约
	ctx := context.Background()
	result, err := client.CallContract(ctx, ethereum.CallMsg{
		To:   &hzbContract,
		Data: data,
	}, nil)
	if err != nil {
		logx.Errorf("调用合约失败: %v", err)
	}

	var balance *big.Int
	err = parsedABI.UnpackIntoInterface(&balance, "balanceOf", result)
	if err != nil {
		logx.Errorf("解析余额失败: %v", err)
	}

	return &types.BlockchainWalletBalanceResponse{
		HzbBalance: balance.String(),
	}, nil
}
